JavaScript language Tips & Tricks
Append an array to another arrayMilliseconds since epochSimulate threads using yield operatorprefix an integer with zerosshuffle the Arraymulti-line textEscape and unescape HTML entitiesRemove an object from an arrayCreates a random alphabetic stringBrainfuck interpreterOptional named function argumentsString converterDisplay the current call stackChange the primitive value of an object with valueOfTransform the arguments object into an arrayConvert a string into a charcode listArray iteration pitfallexceptions for non-fatal errorsA Switch functionA Match functionnew object overrideKind of destructuring assignmentsGenerator ExpressionsAdvanced use of iteratorsExpression ClosuresFunction declaration and expressionFactory method patternClosures by exampleSyntaxErrorReferenceErrorJavaScript Minifier / comment removerJavaScript code beautifier (un-minifier)Auto indent JavaScript code / unobfuscatorObjects, constructor and instanceofObjects private and public membersStack data structureSingleton patternUse Functions as an ObjectE4X add nodesE4X dynamic document creationE4X dynamic tag nameE4X dynamic contentE4X iterationListen a property for changesLogical operators tricksFunctions argument default valueRemove an item by value in an Array objectMultiple-value returnsOperator [ ] and strings ( like charAt() )indexOf() and lastIndexOf() Works on ArrayUsing Array functions on a non-Array objectChange current object (this) of a function callFilter / intercept a function callE4X Query ( like XPath )swap two variablesDestructuring assignment with function argumentsJavaScript scope is not C/C++ scopeJavaScript scope and LET instructionDefer function callsInsert an array in another arrayMultiple string concatenationHTTP headers parserUsing 'with' scope(object).toString()RegExpr.$1Binary with XmlHTTPRequestIterate on valuesExceptions Handling / conditional catch (try catch if)Special charsobject's eval methodeval thisNo Such Method ( noSuchMethod )RegExp replaceValues comparisonundefined, null, 0, false, '', ...constructor property ( InstanceOf + Type )AJAX evaluationComma operatorclosures pitfallsharp variablecommon object between 2 objectsconstructorJavaScript string can contain null chars'new' operator precedenceconstructor usageTo objectSerialize or uneval a variable or an object ( can be nested )JavaScript labelsfor in loopproto ( prototype property )Numbers and floating point errorNumber base conversion ( hexadecimal )try / catch / finallyObject argumentobject and its prototypeRuntime prototype objectfor in loop and undefined valueCall function in parent classgetter and setter functiondefineGetter ( define getter )check if an object or its prototype has a propery (hasOwnProperty)check if a property is enumerable (propertyIsEnumerable)find the getter/setter function of an object ( lookup getter )suppress array element while iterating itJavaScript arraysdelete array elementstore information on the viewer’s computerE-mail ValidationNo Right-ClickDisplay Random QuotesPrevious/Next LinksBookmark a PageEasy Print Page LinkShow Formatted DateComma SeparatorGet the Display Area of a BrowserRedirect with Optional DelayDetect iPhonesPrint Message to Status BarHighlighting textunhighlight textCreating dynamic menusdebuggingxmp, display html tags inside an HTML document1 – Don’t forget var keyword when assigning a variable’s value for the first time.2 – use === instead of ==3 – undefined, null, 0, false, NaN, '' (empty string) are all falsy.4 – Use Semicolons for line termination5 – Create an object constructor6 – Be careful when using typeof, instanceof and constructor.7 – Create a Self-calling Function8 – Get a random item from an array9 – Get a random number in a specific range10 – Generate an array of numbers with numbers from 0 to max11 – Generate a random set of alphanumeric characters12 – Shuffle an array of numbers13 – A string trim function14 – Append an array to another array15 – Transform the arguments object into an array16 – Verify that a given argument is a number17 – Verify that a given argument is an array18 – Get the max or the min in an array of numbers19 – Empty an array20 – Don’t use delete to remove an item from array21 – Truncate an array using length22 – Use logical AND/ OR for conditions23 – Use the map() function method to loop through an array’s items24 – Rounding number to N decimal place25 – Floating point problems26 – Check the properties of an object when using a for-in loop27 – Comma operator28 – Cache variables that need calculation or querying29 – Verify the argument before passing it to isFinite()30 – Avoid negative indexes in arrays31 – Serialization and deserialization (working with JSON)32 – Avoid the use of eval() or the Function constructor33 – Avoid using with() (The good part)34 – Avoid using for-in loop for arrays35 – Pass functions, not strings, to setTimeout() and setInterval()36 – Use a switch/case statement instead of a series of if/else37 – Use switch/case statement with numeric ranges38 – Create an object whose prototype is a given object39 – An HTML escaper function40 – Avoid using try-catch-finally inside a loop41 – Set timeouts to XMLHttpRequests42 – Deal with WebSocket timeout43 – Keep in mind that primitive operations can be faster than function calls. Use VanillaJS.44 – Don’t forget to use a code beautifier when coding. Use JSLint and minification (JSMin, for example) before going live.
Append an array to another array
```
var a = [4,5,6];
var b = [7,8,9];
a.concat(b);
Milliseconds since epoch
+new Date() // 1259359833574
Simulate threads using yield operator
JavaScript 1.7
```
//// thread definition
function Thread( name ) {
for ( var i = 0; i < 5; i++ ) {
Print(name+': '+i);
yield;
}
}
//// thread management
var threads = [];
// thread creation
threads.push( new Thread('foo') );
threads.push( new Thread('bar') );
// scheduler
while (threads.length) {
var thread = threads.shift();
try {
thread.next();
threads.push(thread);
} catch(ex if ex instanceof StopIteration) {}
}
prints:
foo: 0
bar: 0
foo: 1
bar: 1
foo: 2
bar: 2
foo: 3
bar: 3
foo: 4
bar: 4
```
prefix an integer with zeros
```
function PrefixInteger(num, length) {
return (num / Math.pow(10, length)).toFixed(length).substr(2);
}
```
And more efficient:
```
function PrefixInteger(num, length) {
return ( "0000000000000000" + num ).substr( -length );
}
```
Thanks to fritzthe...
And even better:
```
function PrefixInteger(num, length) {
return (Array(length).join('0') + num).slice(-length);
}
```
Thanks to tobeytai...
shuffle the Array
JavaScript 1.?
```
var list = [1,2,3,4,5,6,7,8,9];
list = list.sort(function() Math.random() - 0.5);
Print(list); // prints something like: 4,3,1,2,9,5,6,7,8
```
multi-line text
JavaScript 1.6
var text = <>
this
is
my
multi-line
text
</>.toString();
Print(text);
prints:
```
this
is
my
multi-line
text
```
note
If you want to support special XML chars, you can use a CDATA section:
```
<>
hello
]]>.toString();
```
Escape and unescape HTML entities
```
const entityToCode = { proto: null,
apos:0x0027,quot:0x0022,amp:0x0026,lt:0x003C,gt:0x003E,nbsp:0x00A0,iexcl:0x00A1,cent:0x00A2,pound:0x00A3,
curren:0x00A4,yen:0x00A5,brvbar:0x00A6,sect:0x00A7,uml:0x00A8,copy:0x00A9,ordf:0x00AA,laquo:0x00AB,
not:0x00AC,shy:0x00AD,reg:0x00AE,macr:0x00AF,deg:0x00B0,plusmn:0x00B1,sup2:0x00B2,sup3:0x00B3,
acute:0x00B4,micro:0x00B5,para:0x00B6,middot:0x00B7,cedil:0x00B8,sup1:0x00B9,ordm:0x00BA,raquo:0x00BB,
frac14:0x00BC,frac12:0x00BD,frac34:0x00BE,iquest:0x00BF,Agrave:0x00C0,Aacute:0x00C1,Acirc:0x00C2,Atilde:0x00C3,
Auml:0x00C4,Aring:0x00C5,AElig:0x00C6,Ccedil:0x00C7,Egrave:0x00C8,Eacute:0x00C9,Ecirc:0x00CA,Euml:0x00CB,
Igrave:0x00CC,Iacute:0x00CD,Icirc:0x00CE,Iuml:0x00CF,ETH:0x00D0,Ntilde:0x00D1,Ograve:0x00D2,Oacute:0x00D3,
Ocirc:0x00D4,Otilde:0x00D5,Ouml:0x00D6,times:0x00D7,Oslash:0x00D8,Ugrave:0x00D9,Uacute:0x00DA,Ucirc:0x00DB,
Uuml:0x00DC,Yacute:0x00DD,THORN:0x00DE,szlig:0x00DF,agrave:0x00E0,aacute:0x00E1,acirc:0x00E2,atilde:0x00E3,
auml:0x00E4,aring:0x00E5,aelig:0x00E6,ccedil:0x00E7,egrave:0x00E8,eacute:0x00E9,ecirc:0x00EA,euml:0x00EB,
igrave:0x00EC,iacute:0x00ED,icirc:0x00EE,iuml:0x00EF,eth:0x00F0,ntilde:0x00F1,ograve:0x00F2,oacute:0x00F3,
ocirc:0x00F4,otilde:0x00F5,ouml:0x00F6,divide:0x00F7,oslash:0x00F8,ugrave:0x00F9,uacute:0x00FA,ucirc:0x00FB,
uuml:0x00FC,yacute:0x00FD,thorn:0x00FE,yuml:0x00FF,OElig:0x0152,oelig:0x0153,Scaron:0x0160,scaron:0x0161,
Yuml:0x0178,fnof:0x0192,circ:0x02C6,tilde:0x02DC,Alpha:0x0391,Beta:0x0392,Gamma:0x0393,Delta:0x0394,
Epsilon:0x0395,Zeta:0x0396,Eta:0x0397,Theta:0x0398,Iota:0x0399,Kappa:0x039A,Lambda:0x039B,Mu:0x039C,
Nu:0x039D,Xi:0x039E,Omicron:0x039F,Pi:0x03A0,Rho:0x03A1,Sigma:0x03A3,Tau:0x03A4,Upsilon:0x03A5,
Phi:0x03A6,Chi:0x03A7,Psi:0x03A8,Omega:0x03A9,alpha:0x03B1,beta:0x03B2,gamma:0x03B3,delta:0x03B4,
epsilon:0x03B5,zeta:0x03B6,eta:0x03B7,theta:0x03B8,iota:0x03B9,kappa:0x03BA,lambda:0x03BB,mu:0x03BC,
nu:0x03BD,xi:0x03BE,omicron:0x03BF,pi:0x03C0,rho:0x03C1,sigmaf:0x03C2,sigma:0x03C3,tau:0x03C4,
upsilon:0x03C5,phi:0x03C6,chi:0x03C7,psi:0x03C8,omega:0x03C9,thetasym:0x03D1,upsih:0x03D2,piv:0x03D6,
ensp:0x2002,emsp:0x2003,thinsp:0x2009,zwnj:0x200C,zwj:0x200D,lrm:0x200E,rlm:0x200F,ndash:0x2013,
mdash:0x2014,lsquo:0x2018,rsquo:0x2019,sbquo:0x201A,ldquo:0x201C,rdquo:0x201D,bdquo:0x201E,dagger:0x2020,
Dagger:0x2021,bull:0x2022,hellip:0x2026,permil:0x2030,prime:0x2032,Prime:0x2033,lsaquo:0x2039,rsaquo:0x203A,
oline:0x203E,frasl:0x2044,euro:0x20AC,image:0x2111,weierp:0x2118,real:0x211C,trade:0x2122,alefsym:0x2135,
larr:0x2190,uarr:0x2191,rarr:0x2192,darr:0x2193,harr:0x2194,crarr:0x21B5,lArr:0x21D0,uArr:0x21D1,
rArr:0x21D2,dArr:0x21D3,hArr:0x21D4,forall:0x2200,part:0x2202,exist:0x2203,empty:0x2205,nabla:0x2207,
isin:0x2208,notin:0x2209,ni:0x220B,prod:0x220F,sum:0x2211,minus:0x2212,lowast:0x2217,radic:0x221A,
prop:0x221D,infin:0x221E,ang:0x2220,and:0x2227,or:0x2228,cap:0x2229,cup:0x222A,int:0x222B,
there4:0x2234,sim:0x223C,cong:0x2245,asymp:0x2248,ne:0x2260,equiv:0x2261,le:0x2264,ge:0x2265,
sub:0x2282,sup:0x2283,nsub:0x2284,sube:0x2286,supe:0x2287,oplus:0x2295,otimes:0x2297,perp:0x22A5,
sdot:0x22C5,lceil:0x2308,rceil:0x2309,lfloor:0x230A,rfloor:0x230B,lang:0x2329,rang:0x232A,loz:0x25CA,
spades:0x2660,clubs:0x2663,hearts:0x2665,diams:0x2666
};
var charToEntity = {};
for ( var entityName in entityToCode )
charToEntity[String.fromCharCode(entityToCode[entityName])] = entityName;
function UnescapeEntities(str) str.replace(/&(.+?);/g, function(str, ent) String.fromCharCode( ent[0]!='#' ? entityToCode[ent] : ent[1]=='x' ? parseInt(ent.substr(2),16): parseInt(ent.substr(1)) ) );
function EscapeEntities(str) str.replace(/[^\x20-\x7E]/g, function(str) charToEntity[str] ? '&'+charToEntity[str]+';' : str );
```
Remove an object from an array
JavaScript 1.8
function RemoveArrayElement( array, element ) !!let (pos=array.lastIndexOf(element)) pos != -1 && array.splice(pos, 1);
Creates a random alphabetic string
```
function RandomString(length) {
var str = '';
for ( ; str.length < length; str += Math.random().toString(36).substr(2) );
return str.substr(0, length);
}
```
Brainfuck interpreter
```
var code = '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.';
var inp = '23\n';
var out = '';
var codeSize = code.length;
var i = 0, ip = 0, cp = 0, dp = 0, m = {};
var loopIn = {}, loopOut = {};
var tmp = [];
for ( var cp = 0; cp < codeSize ; cp++ )
if ( code[cp] == '[' )
tmp.push(cp);
else
if ( code[cp] == ']' )
loopOut[loopIn[cp] = tmp.pop()] = cp;
for (var cp = 0; cp < codeSize && i < 100000; cp++, i++) {
switch(code[cp]) {
case '>': dp++; break;
case '<': dp--; break;
case '+': m[dp] = ((m[dp]||0)+1)&255; break
case '-': m[dp] = ((m[dp]||0)-1)&255; break;
case '.': out += String.fromCharCode(m[dp]); break;
case ',': m[dp] = inp.charCodeAt(ip++)||0; break;
case '[': m[dp]||(cp=loopOut[cp]); break;
case ']': cp = loopIn[cp]-1; break;
}
}
Print(out);
```
This Brainfuck program just prints 'Hello World!'
Optional named function arguments
```
function foo({ name:name, project:project}) {
Print( project );
Print( name );
}
foo({ name:'soubok', project:'jslibs' })
foo({ project:'jslibs', name:'soubok'})
```
String converter
JavaScript 1.8
function CreateTranslator(translationTable)
function(s)
s.replace(new RegExp([k for (k in translationTable)].join('|'), 'g'), function(str) translationTable[str]);
exemple of use:
var translationTable = { a:1, bb:2, b:3, c:4 };
var MyTranslater = CreateTranslator( translationTable );
MyTranslater('aabbbc'); // returns: 11234
Display the current call stack
```
function Stack() { try { throw Error() } catch(ex) { return ex.stack } }
print( Stack() );
prints:
Error()@:0
Stack()@test.js:1
@test.js:3
```
Change the primitive value of an object with valueOf
```
function foo() {
this.valueOf = function() {
return 'this is my value';
}
}
var bar = new foo();
Print( bar ); // prints: this is my value
Print( bar == 'this is my value' ) // prints: true
Print( bar === 'this is my value' ) // prints: false
```
Transform the arguments object into an array
JavaScript 1.6
```
function foo() {
var argArray = Array.slice(arguments); // is ['aa',11]
}
foo('aa',11);
```
use also
var argArray = Array.prototype.slice.call(arguments);
Convert a string into a charcode list
Method 1:
JavaScript 1.6
Array.map('foo', function(x) { return String.charCodeAt(x) }) // is [112,111,111]
Method 2:
JavaScript 1.7
[ String.charCodeAt(x) for each ( x in 'foo' ) ] // is [112,111,111]
Array iteration pitfall
```
var foo = [3,4,5];
for ( var i in foo ) {
if ( i == 1 ) {
foo.unshift(6);
}
Print('item: '+foo[i])
}
Print( 'array: '+foo.toSource() )
output:
item: 3
item: 3
item: 4
array: [6, 3, 4, 5]
```
exceptions for non-fatal errors
JavaScript 1.7
```
function ERR() { throw ERR }
function CHK( v ) { return v || ERR() }
try {
var data1 = 'a/b/c';
var arr1 = CHK(data1).split('/');
var data2 = '';
var arr2 = CHK(data2).split('/'); // the exception is throw here
} catch(ex if ex == ERR) {
Print('non fatal error while decoding the data')
}
prints:
a b c
```
A Switch function
JavaScript 1.8
function Switch(i) arguments[++i];
usage:
Print( Switch(2,'aa','bb','cc','dd') ); // prints: cc
Print( Switch(100,'aa','bb','cc','dd') ); // prints: undefined
A Match function
JavaScript 1.8
function Match(v) Array.indexOf(arguments,v,1)-1;
usage:
Print( Match('aa', '0', 'b', 123, 'aa', 8.999 ) ); // prints: 3
Print( Match('Z', 'b', 123, 'aa', 8.999 ) ); // prints: -2 (< 0 is not found)
new object override
JavaScript 1.5
```
function foo() {
return new Array(5,6,7);
}
var bar = new foo();
bar.length // is 3
```
Kind of destructuring assignments
JavaScript 1.7
var { a:x, b:y } = { a:7, b:8 };
Print(x); // prints: 7
Print(y); // prints: 8
Generator Expressions
JavaScript 1.7
[ y for ( y in [5,6,7,8,9] ) ] // is [0,1,2,3,4]
and
[ y for each ( y in [5,6,7,8,9] ) ] // is [5,6,7,8,9]
Because in for extracts index names, and for each extracts the values.
Advanced use of iterators
JavaScript 1.7
```
Number.prototype.iterator = function() {
for ( let i = 0; i < this; i++ )
yield i;
};
for ( let i in 5 )
print(i);
prints:
1
2
3
4
5
```
This make Number object to act as a generator.
Expression Closures
JavaScript 1.8
function(x) x * x;
Note that braces {...} and return are implicit
Function declaration and expression
Function declaration:
```
bar(); // prints: bar
function bar() {
Print('bar');
}
function foo() {
Print('foo');
}
foo(); // prints: foo
```
Function expression:
```
(function foo() {
Print( foo.name );
})(); // prints: foo
foo(); // rise a ReferenceError
!function foo() {
}
foo(); // rise a ReferenceError
var bar = function foo() {
}
foo(); // rise a ReferenceError
```
Factory method pattern
```
Complex = new function() {
function Complex(a, b) {
// ...
}
this.fromCartesian = function(real, mag) {
return new Complex(real, imag);
}
this.fromPolar = function(rho, theta) {
return new Complex(rho * Math.cos(theta), rho * Math.sin(theta));
}
}
var c = Complex.fromPolar(1, Math.pi); // Same as fromCartesian(-1, 0);
```
see factory pattern on wikipedia
Closures by example
JavaScript 1.5
```
function CreateAdder( add ) {
return function( value ) {
return value + add;
}
}
```
usage:
```
var myAdder5 = CreateAdder( 5 );
var myAdder6 = CreateAdder( 6 );
Print( myAdder5( 2 ) ); // prints 7
Print( myAdder6( 4 ) ); // prints 10
```
Further information about Nested functions and closures
SyntaxError
JavaScript 1.5
raised when a syntax error occurs while parsing code in eval()
```
try {
eval('1 + * 5'); // will rise a SyntaxError exception
} catch( ex ) {
Print( ex.constructor == SyntaxError ); // Prints true
}
```
JavaScript 1.7
```
try {
eval('1 + * 5');
} catch( ex if ex instanceof SyntaxError ) {
Print( 'SyntaxError !' ); // prints: SyntaxError !
}
```
ReferenceError
raised when de-referencing an invalid reference.
```
try {
fooBar(); // will rise a ReferenceError exception
} catch( ex ) {
Print( ex.constructor == ReferenceError ); // Prints true
}
```
JavaScript 1.7
```
try {
fooBar();
} catch( ex if ex instanceof ReferenceError ) {
Print( 'ReferenceError !' ); // prints: ReferenceError !
}
```
JavaScript Minifier / comment remover
jslibs
var script = new Script('var a; /* this is a variable */ var b; // another variable');
Print( script.toString() );
prints:
var a;
var b;
javascript
```
function foo() {
var a; // a variable
var b = [1, 2, 3]; // an array
var c = {x: {y: 1}};
function bar() { // my function
return 1 /* 2 */;
}
}
Print( foo.toSource() );
```
JavaScript code beautifier (un-minifier)
function foo() {var a;var b=[1,2,3];var c={x:{y:1}};function bar(){return 1}}
Print( foo.toSource(1) );
prints:
```
function foo() {
var a;
var b = [1, 2, 3];
var c = {x: {y: 1}};
function bar() {
return 1;
}
}
```
Auto indent JavaScript code / unobfuscator
Spidermonkey JavaScript engine only
function foo() { function bar(){};var i=0;for(;i<10;++i) bar(i) }
Print(foo.toSource(2));
prints:
```
function foo() {
function bar() {
}
var i = 0;
for (; i < 10; ++i) {
bar(i);
}
}
```
Objects, constructor and instanceof
JavaScript 1.5
```
function Foo() {
// Foo class
}
var a = new Foo();
Bar.prototype = new Foo();
function Bar() {
// Bar class
}
var b = new Bar();
Print( a.constructor == Foo ); // true
Print( a instanceof Foo ); // true
Print( b.constructor == Foo ); // true
Print( b instanceof Foo ); // true
Print( b.constructor == Bar ); // false !
Print( b instanceof Bar ); // true
```
Objects private and public members
```
function MyConstructor( pub, priv ) {
var privateVariable = priv;
this.publicVariable = pub;
this.SetThePrivateVariable = function( value ) {
privateVariable = value;
}
this.GetThePrivateVariable = function() {
return privateVariable;
}
this.PrintAllVariables = function() {
Print( privateVariable + ',' + this.publicVariable );
}
}
var myObject = new MyConstructor( 123, 456 );
Print( myObject.privateVariable ); // prints: undefined
Print( myObject.publicVariable ); // prints: 123
myObject.PrintAllVariables(); // prints 456,123
myObject.SetThePrivateVariable( 789 );
myObject.PrintAllVariables(); // prints 789,123
```
Stack data structure
JavaScript 1.5
Array object has all needed methods to be used as a stack.
```
var stack = [];
stack.push( 111 );
stack.push( 2.22 );
stack.push( 'ccc' );
Print( stack ); // prints: 111,2.22,ccc
Print( stack.pop() ); // prints: ccc
Print( stack.pop() ); // prints: 2.22
```
Singleton pattern
JavaScript 1.5
The singleton pattern is a design pattern that is used to restrict instantiation of a class to one object.
This is useful when exactly one object is needed to coordinate actions across the system.
```
function MySingletonClass() {
if ( arguments.callee._singletonInstance )
return arguments.callee._singletonInstance;
arguments.callee._singletonInstance = this;
this.Foo = function() {
// ...
}
}
var a = new MySingletonClass()
var b = MySingletonClass()
Print( a === b ); // prints: true
```
Use Functions as an Object
JavaScript 1.5
```
function Counter() {
if ( !arguments.callee.count ) {
arguments.callee.count = 0;
}
return arguments.callee.count++;
}
Print( Counter() ); // prints: 0
Print( Counter() ); // prints: 1
Print( Counter() ); // prints: 2
```
E4X add nodes
JavaScript 1.6
var x = <store/>;
x.* += <item price="10" />;
x.* += <item price="15" />;
Print( x.toXMLString() );
prints:
<store>
<item price="10"/>
<item price="15"/>
</store>
E4X dynamic document creation
JavaScript 1.6
var html = <html/>;
html.head.title = "My Page Title";
html.body.@bgcolor = "#e4e4e4";
html.body.form.@name = "myform";
html.body.form.@action = "someurl.jss";
html.body.form.@method = "post";
html.body.form.@onclick = "return somejs();";
html.body.form.input[0] = "";
html.body.form.input[0].@name = "test";
Print(html.toXMLString());
prints:
<html>
<head>
<title>My Page Title</title>
</head>
<body bgcolor="#e4e4e4">
<form name="myform" action="someurl.jss" method="post" onclick="return somejs();">
<input name="test"></input>
</form>
</body>
</html>
E4X dynamic tag name
JavaScript 1.6
var nodeName = 'FOO';
if ( isXMLName(nodeName) ) { // assert that nodeName can be used as a node name
var x = <{nodeName}>test</{nodeName}>
Print( x.toXMLString() ); // prints: <FOO>test</FOO>
}
E4X dynamic content
JavaScript 1.6
var content = 'FOO';
var x = <item>{content}</item>
Print( x.toXMLString() ); // prints: <item>FOO</item>
E4X iteration
JavaScript 1.6
```
var sales =
;
for each( var price in sales..@price ) {
Print( price + '\n' );
}
prints:
4
3
5
```
Listen a property for changes
```
function onFooChange( id, oldval, newval ) {
Print( id + " property changed from " + oldval + " to " + newval );
return newval;
}
var o = { foo:5 };
o.watch( 'foo', onFooChange );
o.foo = 6;
delete o.foo;
o.foo = 7;
o.unwatch('foo');
o.foo = 8;
prints:
foo property changed from 5 to 6
foo property changed from undefined to 7
```
Logical operators tricks
var a = 5;
a == 5 && Print( 'a is 5 \n' );
a == 7 || Print( 'a is not 7 \n' );
prints:
a is 5
a is not 7
Functions argument default value
```
function foo( a, b ) {
a = a || '123';
b = b || 55;
Print( a + ',' + b );
}
foo(); // prints: 123,55
foo('bar'); // prints: bar,55
foo('x', 'y'); // prints x,y
 but:
foo(0,''); // prints: 123,55
```
because 0 and '' are evaluated as false !
Remove an item by value in an Array object
var arr = ['a', 'b', 'c', 'd'];
var pos = arr.indexOf( 'c' );
pos > -1 && arr.splice( pos, 1 );
Print( arr ); // prints: a,b,d
Multiple-value returns
JavaScript 1.7
```
function f() {
return [1, 2];
}
var [a, b] = f();
Print( a + ' ' + b ); // prints: 1 2
```
Operator [ ] and strings ( like charAt() )
JavaScript 1.6
var str = 'foobar';
Print( str[4] );
prints:
a
indexOf() and lastIndexOf() Works on Array
JavaScript 1.6
var obj = {};
var arr = [ 'foo', 567, obj, 12.34 ];
Print( arr.indexOf(obj) ); // prints: 2
Using Array functions on a non-Array object
JavaScript 1.7
var obj = {};
Array.push(obj, 'foo');
Array.push(obj, 123);
Array.push(obj, 5.55);
Print( obj.toSource() ); // prints: ({0:"foo", length:3, 1:123, 2:5.55})
Change current object (this) of a function call
```
function test(arg) {
Print( this[0]+' '+this[1]+' '+arg );
}
var arr = ['foo', 'bar'];
test.call(arr, 'toto'); // prints: foo bar toto
```
Filter / intercept a function call
```
function bar(a, b, c, d, e, f) {
Print(a, b, c, d, e, f)
}
function foo() {
bar.apply(this, arguments);
}
foo(1, 2, 3, 4, 5, 6); // prints: 123456
```
E4X Query ( like XPath )
JavaScript 1.6
```
var xml =
Print( xml.data.(@id==1).@text );
var myid = 2;
Print( xml.data.(@id==myid).@text );
prints:
foo
bar
```
swap two variables
JavaScript 1.7
var a = 1;
var b = 2;
[a,b] = [b,a];
Destructuring assignment with function arguments
JavaScript 1.7
```
function foo( [a,b] ) {
Print(a);
Print(b);
}
foo( [12,34] );
Prints:
12
34
```
JavaScript scope is not C/C++ scope
```
if ( false ) { // never reach the next line
var foo = 123;
}
Print(foo); // prints: undefined ( but is defined )
Print(bar); // failed: ReferenceError: bar is not defined
```
JavaScript scope and LET instruction
JavaScript 1.7
var x = 5;
var y = 0;
let (x = x+10, y = 12) {
Print(x+y);
}
Print(x+y);
prints:
27
5
or,
for ( let i=0 ; i < 10 ; i++ ) {
Print(i + ' ');
}
Print(i);
prints:
0 1 2 3 4 5 6 7 8 9 test.js:4: ReferenceError: i is not defined
Defer function calls
```
var opList = [];
function deferCall( text, value ) {
opList.push(arguments)
}
function doCall(func) {
while (opList.length)
func.apply(this,opList.shift());
}
deferCall( 'one', 1 );
deferCall( 'titi', 'toto' );
deferCall( 5, 'foo' );
function callLater(a,b) {
Print(a+', '+b);
}
doCall( callLater )
Prints:
one, 1
titi, toto
5, foo
```
Insert an array in another array
```
var a = [1,2,3,7,8,9]
var b = [4,5,6]
var insertIndex = 3;
a.splice.apply(a, Array.concat(insertIndex, 0, b));
Print(a); // prints: 1,2,3,4,5,6,7,8,9
```
Multiple string concatenation
var html = ['aaa', 'bbb', 'ccc', ...].join('');
Is faster than:
var html = 'aaa' + 'bbb' + 'ccc' + ...;
This is true with a big number of elements ( > 5000 )
HTTP headers parser
```
var rexp_keyval = /(.?): ?(.?)\r?\n/g;
function headersToObject( allHeaders ) {
var res, hdrObj = {};
for ( rexp_keyval.lastIndex = 0; res = rexp_keyval.exec(allHeaders); hdrObj[res[1]] = res[2])
return hdrObj;
}
```
Using 'with' scope
with({ a:5 }) function toto() { return a }
toto() // returns 5
(object).toString()
var a = { toString:function() { return '123'; } }
Print(a); // prints '123', and not [Object object]
RegExpr.$1
var re = /a(.*)/
'abcd'.match(re)
Print( RegExp.$1 ) // prints 'bcd'
Binary with XmlHTTPRequest
browser related example
var req = new XMLHttpRequest();
req.open('GET', "http://code.google.com/images/code_sm.png",false);
req.overrideMimeType('text/plain; charset=x-user-defined');
//req.overrideMimeType('application/octet-stream');
req.send(null);
var val = req.responseText;
Print( escape(val.substr(0,10)) );
Iterate on values
JavaScript 1.6
for each ( var i in [3,23,4] )
Print(i)
Prints:
3
23
4
Exceptions Handling / conditional catch (try catch if)
```
function Toto(){}
function Titi(){}
try {
throw new Titi()
} catch ( err if err instanceof Toto ) {
Print('toto')
} catch ( err if err instanceof Titi ) {
Print('titi')
} catch(ex) {
throw(ex);
}
```
Special chars
$=4
_=5
Print( _+$)
prints:
9
object's eval method
var foo = { bar:123 };
foo.eval('bar') // returns 123
var foo = { bar:123 };
with ( foo )
var val = eval( 'bar' );
Print( val ); // returns 123
eval this
```
function test() {
Print(eval('this'));
}
test.call(123)
prints:
123
```
No Such Method ( noSuchMethod )
var o = {}
o.__noSuchMethod__ = function(arg){ Print('unable to call "'+arg+'" function') }
o.foo(234)
prints:
unable to call "foo" function
RegExp replace
```
function Replacer( conversionObject ) {
var regexpStr = '';
for ( var k in conversionObject )
regexpStr += (regexpStr.length ? '|' : '') + k;
var regexpr = new RegExp(regexpStr,'ig'); // g: global, m:multi-line i: ignore case
return function(s) { return s.replace(regexpr, function(str, p1, p2, offset, s) { var a = conversionObject[str]; return a == undefined ? str : a }) }
}
var myReplacer = Replacer( { '
':'\n', '&':'&', '<':'<', '>':'>', '"':'"' } );
Print( myReplacer('aa
a &&&<') );
prints:
aa
a &&&<
```
Values comparison
```
[4] === 4 // is: false
[4] == 4 // is: true
'0' == 0 // is: true
'0' === 0 // is: false
```
undefined, null, 0, false, '', ...
```
var a = { b:undefined, c:null, d:0, f:'' }
a['b'] // is: undefined
a['e'] // is: undefined
'b' in a // is: true
'e' in a // is: false
Boolean(a.b) // is: false
Boolean(a.c) // is: false
Boolean(a.d) // is: false
Boolean(a.e) // is: false !
Boolean(a.f) // is: false
typeof( asvqwfevqwefq ) == 'undefined' // =true
Print( '' == false ); // prints: true
Print( 0 == false ); // prints: true
Print( [] == false ); // prints: true
Print( [] == '' ); // prints: true
Print( '' == 0 ); // prints: true
Print( [] == 0 ); // prints: true
```
constructor property ( InstanceOf + Type )
var a = {};
a.constructor === Object // is: true
AJAX evaluation
```
var a = {
b:function() { Print(123) }
}
var body = 'b();';
with(a) { eval(body) }; // Prints 123
```
Comma operator
```
var a = 0;
var b = ( a++, 99 );
a // is: 1
b // is: 99
var i = 0;
while( Print('x '), i++<10 )
Print(i + ' ')
```
prints:
x 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
closures pitfall
```
var a = [];
for ( var i=0; i<10; i++ ) {
a[i] = function() { Print(i); }
}
a0; // is: 10
a1; // is: 10
a2; // is: 10
a3; // is: 10
```
simpler case:
var i = 5;
function foo() { Print(i) }
foo(); // prints 5
i = 6;
foo(); // prints 6
Closure definition
A closure occurs when one function appears entirely within the body of another, and the inner function refers to local variables of the outer function.
links
obligated lecture to understand closures
In the first example, you can avoid the behavior using the let instruction:
```
var a = [];
for ( var i=0; i<10; i++ ) {
let j = i;
a[i] = function() { Print(j); }
}
```
In this case, each instances of the (anonymous) inner function refer to different instances of variable j.
sharp variable
```
var a = { titi:#1={}, toto:#1# };
a.titi === a.toto; // is: true
var a = { b:#1={ c:#1# } }
// a.b.c.c.c.c.c.c...
```
common object between 2 objects
```
function a() {}
a.prototype = { b:{} }
c = new a;
d = new a;
c.b.e = 2;
c.b === d.b // is: true !
d.b.e // is: 2
```
constructor
```
function a( b ) {
Print(b);
}
c.prototype = new a;
function c( arg ) {
this.constructor.apply( this, arg );
};
o = new c( [1,2,3] );
prints:
undefined
1
```
JavaScript string can contain null chars
var test = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00';
test.length // is: 10
'new' operator precedence
```
function test() {
this.toto = 1234;
}
(new test()).toto // ok ( logical way )
new test().toto // ok
new test.toto // bad !
(new test).toto // ok
```
constructor usage
```
function toto( val ) { // parent class
this.print = function() {
Print( val );
}
}
titi.prototype = new toto;
function titi( val ) { // child class
this.constructor(val);
}
(new titi(7)).print(); // prints 7
```
To object
var obj = Object(123);
obj.foo = 678;
Print( typeof( obj ) + ', ' + obj + ', ' + obj.foo ); // prints: object, 123, 678
Serialize or uneval a variable or an object ( can be nested )
```
var o = { a:123, b:'test', c:function() { return 987; } }
Print( o.toSource() ); // prints: ({a:123, b:"test", c:(function () {return 987;})})
Print( uneval(o) ); // prints: ({a:123, b:"test", c:(function () {return 987;})})
```
JavaScript labels
xxx: {
Print( 111 )
break xxx;
Print( 222 )
}
prints:
111
for in loop
for ( var i in function(){ return [1, 2, 3] }() )
Print( i );
prints:
0
1
2
proto ( prototype property )
var a = {}
var b = {}
a.__proto__ == b.__proto__ // is: true
Numbers and floating point error
Print( 1000000000000000128 ); // prints 1000000000000000100
Number base conversion ( hexadecimal )
```
(255).toString(16); // is: ff
parseInt( 'ff', 16 ) // is: 255
parseInt('0xff'); // is 255
```
try / catch / finally
```
try {
} catch(ex) {
Print('catch')
} finally {
Print('finally')
}
prints:
finally
```
Object argument
```
var proto = {
x: function() { return 'x' }
}
var o1 = new Object( proto );
var o2 = new Object( proto );
o1 == o2 // is: true
```
object and its prototype
```
function obj() {}
obj.prototype = { x:1 };
var b = new obj;
obj.prototype = { x:2 };
var c = new obj;
c.x == b.x // is: false
```
Runtime prototype object
```
var proto1 = {
a:function(){ return 1 }
}
var proto2 = {
a:function(){ return 2 }
}
function createObject( proto ) {
var cl = function() {}
cl.prototype = proto;
return new cl;
}
var v1 = createObject( proto1 ).a
var v2 = createObject( proto2 ).a
Print( v1() );
Print( v2() );
Print( createObject( proto1 ).a === createObject( proto1 ).a );
prints:
1
2
true
```
for in loop and undefined value
var o = { x:undefined }
for ( var i in o )
Print(i)
prints:
x
Call function in parent class
```
toto.prototype = new function() {
this.a = function() {
Print(456)
}
};
function toto() {
this.a=function(){
Print(123)
toto.prototype.a.call(this); // or: this.__proto__.a();
}
}
var o = new toto;
o.a();
prints:
123
456
```
getter and setter function
```
abcd getter = function() {
Print(345);
}
abcd;
abcd;
abcd;
prints:
345
345
345
```
Beware
The previous syntax used to define a getter is highly deprecated, and should be replaced with:
```
defineGetter('abcd', function() {
Print(345);
});
```
defineGetter ( define getter )
o = {}
o.__defineGetter__('x', function(){ Print('xxx')} )
o.x
prints:
xxx
check if an object or its prototype has a propery (hasOwnProperty)
```
var o = { a:1 }
o.proto = { b:2 }
o.hasOwnProperty('a'); // is: true
o.hasOwnProperty('b'); // is: false
```
check this article about hasOwnProperty function
check if a property is enumerable (propertyIsEnumerable)
```
var o = { a:1 }
o.propertyIsEnumerable( 'a' ); // is: true
[].propertyIsEnumerable( 'splice' ); // is: false
```
find the getter/setter function of an object ( lookup getter )
```
function test() {
this.x getter = function(){ Print( 'getter' ) }
this.x setter = function(){ Print( 'setter' ) }
}
var t = new test
Print( t.lookupGetter( 'x' ) );
prints:
function () {
Print("getter");
}
```
suppress array element while iterating it
the following example will failed :
```
var a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
for ( var i in a ) {
if ( a[i] == 1 || a[i] == 2 )
a.splice( i, 1 );
}
Print( a ); // prints: 0,2,3,4,5,6,7,8,9
Print( a.length ); // prints: 9
```
We can use :
a[i] == undefined;
Or start from the end :
```
var a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
for ( var i = a.length - 1; i >= 0; i-- ) {
if ( a[i] == 0 || a[i] == 8 )
a.splice( i, 1 );
}
Print( a ); // prints: 1,2,3,4,5,6,7,9
Print( a.length ); // prints: 8
```
JavaScript arrays
```
var a = [ 1,2,3 ];
a.x = 'xxx';
for ( var i = 0; i < a.length; i++ )
Print('a: '+a[i]);
for ( var i in a )
Print('b: '+a[i]);
prints:
a: 1
a: 2
a: 3
b: 1
b: 2
b: 3
b: xxx
```
delete array element
The following do not work:
var ti = [5,6,7,8];
ti.length // is: 4
delete ti[3]
ti.length // is: 4
Use 'splice' instead:
ti.splice(3, 1);
store information on the viewer’s computer
Preload your images
Quick Sample
E-mail Validation
Body:
No Right-Click
Quick Sample
Display Random Quotes
Quick Sample
Head:
Body:
Previous/Next Links
Quick Sample
Previous Page | Next Page
What does the JavaScript snippet do?
This snippet is great if you have multiple pages on an article or tutorial. It will allow the user the browse between the pages with ease. It is also small and light weight from a resource point of view.
Bookmark a Page
Quick Sample
Add to Favorites
Easy Print Page Link
Quick Sample
Print Page
Show Formatted Date
Quick Sample
Head:
Body:
Comma Separator
Quick Sample
Head:
Body:
Get the Display Area of a Browser
Quick Sample
Redirect with Optional Delay
Quick Sample
Detect iPhones
Sample
Print Message to Status Bar
Quick Sample
Highlighting text
There are many jQuery plugins to highlight text.
This technique is easy without any libraries. The script returns the original text with the terms wrapped in a tag so they can be styled with CSS.
function highlight(text, words, tag) {
// Default tag if no tag is provided
tag = tag || 'span';
var i, len = words.length, re;
for (i = 0; i < len; i++) {
// Global regex to highlight all matches
re = new RegExp(words[i], 'g');
if (re.test(text)) {
text = text.replace(re, '<'+ tag +' class="highlight">$&'+ tag +'>');
}
}
return text;
}
unhighlight text
function unhighlight(text, tag) {
// Default tag if no tag is provided
tag = tag || 'span';
var re = new RegExp('(<'+ tag +'.+?>|<\/'+ tag +'>)', 'g');
return text.replace(re, '');
}
Usage:
$('p').html( highlight(
$('p').html(), // the text
['foo', 'bar', 'baz', 'hello world'], // list of words or phrases to highlight
'strong' // custom tag
));
Creating dynamic menus
function makeMenu(items, tags) {
tags = tags || ['ul', 'li']; // default tags
var parent = tags[0];
var child = tags[1];
var item, value = '';
for (var i = 0, l = items.length; i < l; i++) {
item = items[i];
// Separate item and value if value is present
if (/:/.test(item)) {
item = items[i].split(':')[0];
value = items[i].split(':')[1];
}
// Wrap the item in tag
items[i] = '<'+ child +' '+
(value && 'value="'+value+'"') +'>'+ // add value if present
item +''+ child +'>';
}
return '<'+ parent +'>'+ items.join('') +''+ parent +'>';
}
Usage:
// Dropdown select month
makeMenu(
['January:JAN', 'February:FEB', 'March:MAR'], // item:value
['select', 'option']
);
// List of groceries
makeMenu(
['Carrots', 'Lettuce', 'Tomatos', 'Milk'],
['ol', 'li']
);
debugging
x <- tryCatch(
expr,
warning=function(w){ return(paste( "Warning:", conditionMessage(w)))},
error = function(e) { return(paste( "Error:", conditionMessage(e)))},
finally={ print("This is try-catch output.")}
)
xmp, display html tags inside an HTML document
This is my html inside html.
Can also add styles and formatting inside as well.
1 – Don’t forget var keyword when assigning a variable’s value for the first time.
Assignment to an undeclared variable automatically results in a global variable being created. Avoid global variables.
2 – use === instead of ==
The == (or !=) operator performs an automatic type conversion if needed. The === (or !==) operator will not perform any conversion. It compares the value and the type, which could be considered faster than ==.
[10] === 10 // is false
[10] == 10 // is true
'10' == 10 // is true
'10' === 10 // is false
[] == 0 // is true
[] === 0 // is false
'' == false // is true but true == "a" is false
'' === false // is false
3 – undefined, null, 0, false, NaN, '' (empty string) are all falsy.
4 – Use Semicolons for line termination
The use of semi-colons for line termination is a good practice. You won’t be warned if you forget it, because in most cases it will be inserted by the JavaScript parser. For more details about why you should use semi-colons, take a look to this artice: http://davidwalsh.name/javascript-semicolons.
5 – Create an object constructor
function Person(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
var Saad = new Person("Saad", "Mousliki");
6 – Be careful when using typeof, instanceof and constructor.
typeof : a JavaScript unary operator used to return a string that represents the primitive type of a variable, don’t forget that typeof null will return “object”, and for the majority of object types (Array, Date, and others) will return also “object”.
constructor : is a property of the internal prototype property, which could be overridden by code.
instanceof : is another JavaScript operator that check in all the prototypes chain the constructor it returns true if it’s found and false if not.
var arr = ["a", "b", "c"];
typeof arr; // return "object"
arr instanceof Array // true
arr.constructor(); //[]
7 – Create a Self-calling Function
This is often called a Self-Invoked Anonymous Function or Immediately Invoked Function Expression (IIFE). It is a function that executes automatically when you create it, and has the following form:
(function(){
// some private code that will be executed automatically
})();
(function(a,b){
var result = a+b;
return result;
})(10,20)
8 – Get a random item from an array
var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];
var randomItem = items[Math.floor(Math.random() * items.length)];
9 – Get a random number in a specific range
This code snippet can be useful when trying to generate fake data for testing purposes, such as a salary between min and max.
var x = Math.floor(Math.random() * (max - min + 1)) + min;
10 – Generate an array of numbers with numbers from 0 to max
var numbersArray = [] , max = 100;
for( var i=1; numbersArray.push(i++) < max;); // numbers = [1,2,3 ... 100]
11 – Generate a random set of alphanumeric characters
function generateRandomAlphaNum(len) {
var rdmString = "";
for( ; rdmString.length < len; rdmString += Math.random().toString(36).substr(2));
return rdmString.substr(0, len);
}
12 – Shuffle an array of numbers
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() - 0.5});
/* the array numbers will be equal for example to [120, 5, 228, -215, 400, 458, -85411, 122205] */
A better option could be to implement a random sort order by code (e.g. : Fisher-Yates shuffle), than using the native sort JavaScript function. For more details take a look to this discussion.
13 – A string trim function
The classic trim function of Java, C#, PHP and many other language that remove whitespace from a string doesn’t exist in JavaScript, so we could add it to the String object.
String.prototype.trim = function(){return this.replace(/^s+|s+$/g, "");};
A native implementation of the trim() function is available in the recent JavaScript engines.
14 – Append an array to another array
var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 will be equal to [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
15 – Transform the arguments object into an array
var argArray = Array.prototype.slice.call(arguments);
16 – Verify that a given argument is a number
function isNumber(n){
return !isNaN(parseFloat(n)) && isFinite(n);
}
17 – Verify that a given argument is an array
function isArray(obj){
return Object.prototype.toString.call(obj) === '[object Array]' ;
}
Note that if the toString() method is overridden, you will not get the expected result using this trick.
Or use…
Array.isArray(obj); // its a new Array method
You could also use instanceof if you are not working with multiple frames. However, if you have many contexts, you will get a wrong result.
var myFrame = document.createElement('iframe');
document.body.appendChild(myFrame);
var myArray = window.frames[window.frames.length-1].Array;
var arr = new myArray(a,b,10); // [a,b,10]
// instanceof will not work correctly, myArray loses his constructor
// constructor is not shared between frames
arr instanceof Array; // false
18 – Get the max or the min in an array of numbers
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
var maxInNumbers = Math.max.apply(Math, numbers);
var minInNumbers = Math.min.apply(Math, numbers);
19 – Empty an array
var myArray = [12 , 222 , 1000 ];
myArray.length = 0; // myArray will be equal to [].
20 – Don’t use delete to remove an item from array
Use splice instead of using delete to delete an item from an array. Using delete replaces the item with undefined instead of the removing it from the array.
Instead of…
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
delete items[3]; // return true
items.length; // return 11
/* items will be equal to [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */
Use…
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
items.splice(3,1) ;
items.length; // return 10
/* items will be equal to [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */
The delete method should be used to delete an object property.
21 – Truncate an array using length
Like the previous example of emptying an array, we truncate it using the length property.
var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].
As a bonus, if you set the array length to a higher value, the length will be changed and new items will be added with undefined as a value. The array length is not a read only property.
myArray.length = 10; // the new array length is 10
myArray[myArray.length - 1] ; // undefined
22 – Use logical AND/ OR for conditions
var foo = 10;
foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();
foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();
The logical OR could also be used to set a default value for function argument.
function doSomething(arg1){
arg1 = arg1 || 10; // arg1 will have 10 as a default value if it’s not already set
}
23 – Use the map() function method to loop through an array’s items
var squares = [1,2,3,4].map(function (val) {
return val * val;
});
// squares will be equal to [1, 4, 9, 16]
24 – Rounding number to N decimal place
var num =2.443242342;
num = num.toFixed(4); // num will be equal to 2.4432
NOTE : the toFixed() function returns a string and not a number.
25 – Floating point problems
0.1 + 0.2 === 0.3 // is false
9007199254740992 + 1 // is equal to 9007199254740992
9007199254740992 + 2 // is equal to 9007199254740994
Why does this happen? 0.1 +0.2 is equal to 0.30000000000000004. What you need to know is that all JavaScript numbers are floating points represented internally in 64 bit binary according to the IEEE 754 standard. For more explanation, take a look to this blog post.
You can use toFixed() and toPrecision() to resolve this problem.
26 – Check the properties of an object when using a for-in loop
This code snippet could be useful in order to avoid iterating through the properties from the object’s prototype.
for (var name in object) {
if (object.hasOwnProperty(name)) {
// do something with name
}
}
27 – Comma operator
var a = 0;
var b = ( a++, 99 );
console.log(a); // a will be equal to 1
console.log(b); // b is equal to 99
28 – Cache variables that need calculation or querying
In the case of a jQuery selector, we could cache the DOM element.
var navright = document.querySelector('#right');
var navleft = document.querySelector('#left');
var navup = document.querySelector('#up');
var navdown = document.querySelector('#down');
29 – Verify the argument before passing it to isFinite()
isFinite(0/0) ; // false
isFinite("foo"); // false
isFinite("10"); // true
isFinite(10); // true
isFinite(undefined); // false
isFinite(); // false
isFinite(null); // true !!!
30 – Avoid negative indexes in arrays
var numbersArray = [1,2,3,4,5];
var from = numbersArray.indexOf("foo") ; // from is equal to -1
numbersArray.splice(from,2); // will return [5]
Make sure that the arguments passed to splice are not negative.
31 – Serialization and deserialization (working with JSON)
var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };
var stringFromPerson = JSON.stringify(person);
/* stringFromPerson is equal to "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}" */
var personFromString = JSON.parse(stringFromPerson);
/* personFromString is equal to person object */
32 – Avoid the use of eval() or the Function constructor
Use of eval or the Function constructor are expensive operations as each time they are called script engine must convert source code to executable code.
var func1 = new Function(functionCode);
var func2 = eval(functionCode);
33 – Avoid using with() (The good part)
Using with() inserts a variable at the global scope. Thus, if another variable has the same name it could cause confusion and overwrite the value.
34 – Avoid using for-in loop for arrays
Instead of using…
var sum = 0;
for (var i in arrayNumbers) {
sum += arrayNumbers[i];
}
…it’s better to use…
var sum = 0;
for (var i = 0, len = arrayNumbers.length; i < len; i++) {
sum += arrayNumbers[i];
}
As a bonus, the instantiation of i and len is executed once because it’s in the first statement of the for loop. Thsi is faster than using…
for (var i = 0; i < arrayNumbers.length; i++)
Why? The length of the array arrayNumbers is recalculated every time the loop iterates.
NOTE : the issue of recalculating the length in each iteration was fixed in the latest JavaScript engines.
35 – Pass functions, not strings, to setTimeout() and setInterval()
If you pass a string into setTimeout() or setInterval(), the string will be evaluated the same way as with eval, which is slow. Instead of using…
setInterval('doSomethingPeriodically()', 1000);
setTimeout('doSomethingAfterFiveSeconds()', 5000);
…use…
setInterval(doSomethingPeriodically, 1000);
setTimeout(doSomethingAfterFiveSeconds, 5000);
36 – Use a switch/case statement instead of a series of if/else
Using switch/case is faster when there are more than 2 cases, and it is more elegant (better organized code). Avoid using it when you have more than 10 cases.
37 – Use switch/case statement with numeric ranges
Using a switch/case statement with numeric ranges is possible with this trick.
function getCategory(age) {
var category = "";
switch (true) {
case isNaN(age):
category = "not an age";
break;
case (age >= 50):
category = "Old";
break;
case (age <= 20):
category = "Baby";
break;
default:
category = "Young";
break;
};
return category;
}
getCategory(5); // will return "Baby"
38 – Create an object whose prototype is a given object
It’s possible to write a function that creates an object whose prototype is the given argument like this…
function clone(object) {
function OneShotConstructor(){};
OneShotConstructor.prototype= object;
return new OneShotConstructor();
}
clone(Array).prototype ; // []
39 – An HTML escaper function
function escapeHTML(text) {
var replacements= {"<": "<", ">": ">","&": "&", """: """};
return text.replace(/[<>&"]/g, function(character) {
return replacements[character];
});
}
40 – Avoid using try-catch-finally inside a loop
The try-catch-finally construct creates a new variable in the current scope at runtime each time the catch clause is executed where the caught exception object is assigned to a variable.
Instead of using…
var object = ['foo', 'bar'], i;
for (i = 0, len = object.length; i
try {
// do something that throws an exception
}
catch (e) {
// handle exception
}
}
…use…
var object = ['foo', 'bar'], i;
try {
for (i = 0, len = object.length; i
// do something that throws an exception
}
}
catch (e) {
// handle exception
}
41 – Set timeouts to XMLHttpRequests
You could abort the connection if an XHR takes a long time (for example, due to a network issue), by using setTimeout() with the XHR call.
var xhr = new XMLHttpRequest ();
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
clearTimeout(timeout);
// do something with response data
}
}
var timeout = setTimeout( function () {
xhr.abort(); // call error callback
}, 60*1000 /* timeout after a minute */ );
xhr.open('GET', url, true);
xhr.send();
As a bonus, you should generally avoid synchronous XHR calls completely.
42 – Deal with WebSocket timeout
Generally when a WebSocket connection is established, a server could time out your connection after 30 seconds of inactivity. The firewall could also time out the connection after a period of inactivity.
To deal with the timeout issue you could send an empty message to the server periodically. To do this, add these two functions to your code: one to keep alive the connection and the other one to cancel the keep alive. Using this trick, you’ll control the timeout.
Add a timerID…
var timerID = 0;
function keepAlive() {
var timeout = 15000;
if (webSocket.readyState == webSocket.OPEN) {
webSocket.send('');
}
timerId = setTimeout(keepAlive, timeout);
}
function cancelKeepAlive() {
if (timerId) {
cancelTimeout(timerId);
}
}
The keepAlive() function should be added at the end of the onOpen() method of the webSocket connection and the cancelKeepAlive() at the end of the onClose() method.
43 – Keep in mind that primitive operations can be faster than function calls. Use VanillaJS.
For example, instead of using…
var min = Math.min(a,b);
A.push(v);
…use…
var min = a < b ? a : b;
A[A.length] = v;
44 – Don’t forget to use a code beautifier when coding. Use JSLint and minification (JSMin, for example) before going live.
code beautifier
. jsbeautifier